package com.xqq.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 封装了两个方法
 * 分别用于get请求和post请求
 */

@Slf4j
public class HttpUtil {
    // 封装get请求
    public static String sendGet(String url, Map<String, String> params) {
        log.info("远程调用入参为:"+ JSON.toJSONString(params));
        CloseableHttpClient httpClient = null;
        HttpGet httpGet = null;
        CloseableHttpResponse response = null;
        String result = "";
        // 调用失败或异常的情况下重试三次
        String countStr = "";
        int count = 0;
        do {
            try {
                httpClient = HttpClientBuilder.create().build();
                httpGet = new HttpGet(url);
                // 设置参数
                if (null != params && params.size() > 0) {
                    List<BasicNameValuePair> pairList = new ArrayList<>();
                    params.forEach((x, y) -> pairList.add(new BasicNameValuePair(x, y)));
                    UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(pairList, "utf-8");
                    // 将参数转成page=1&limit=5格式
                    String param = EntityUtils.toString(urlEncodedFormEntity, "utf-8");
                    httpGet = new HttpGet(url + "?" + param);
                }
                response = httpClient.execute(httpGet);
                // 获取http状态码，非200和非201的都不是成功
                int httpCode = response.getStatusLine().getStatusCode();
                if (httpCode != 200 && httpCode != 201) {
                    log.info("远程调用失败，httpCode为："+ httpCode);
                    countStr = "ERROR";
                    return "ERROR";
                }
                result = EntityUtils.toString(response.getEntity());
            } catch (IOException e) {
                log.error("远程调用失败,异常信息为：{}", e);
                countStr = "ERROR";
                return "ERROR";
            } finally {
                close(response, httpGet, httpClient);
            }
        } while (countStr.equals("ERROR") && count <= 3);
        return result;
    }

    // 封装post请求
    public static String sendPostJson(String url, Map<String, String> params) {
        log.info("远程调用入参为:"+ JSON.toJSONString(params));
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        CloseableHttpResponse response = null;
        String result = "";
        String countStr = "";
        int count = 0;
        do {
            try {
                httpClient = HttpClientBuilder.create().build();
                httpPost = new HttpPost(url);
                // 设置参数
                if (null != params && params.size() > 0) {
                    String paramJson = JSONObject.toJSONString(params);
                    StringEntity stringEntity = new StringEntity(paramJson, "utf-8");
                    stringEntity.setContentType("application/json;charset=utf-8");
                    httpPost.setEntity(stringEntity);
                }
                response = httpClient.execute(httpPost);
                // 获取http状态码，非200和非201的都不是成功
                int httpCode = response.getStatusLine().getStatusCode();
                if (httpCode != 200 && httpCode != 201) {
                    log.info("远程调用失败，httpCode为："+ httpCode);
                    countStr = "ERROR";
                    return "ERROR";
                }
                result = EntityUtils.toString(response.getEntity());
            } catch (IOException e) {
                log.error("远程调用失败,异常信息为：{}", e);
                countStr = "ERROR";
                return "ERROR";
            } finally {
                close(response, httpPost, httpClient);
            }
        } while (countStr.equals("ERROR") && count <= 3);
        return result;
    }

    public static void close(CloseableHttpResponse response, HttpRequestBase httpRequestBase, CloseableHttpClient httpClient) {
        try {
            if (response != null) {
                response.close();
            }

            if (httpRequestBase != null) {
                httpRequestBase.releaseConnection();
            }

            if (httpClient != null) {
                httpClient.close();
            }
        } catch (IOException e) {

            log.error("异常，{}",e);
        }
    }


}

